package com.bjsxt.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.bjsxt.matcher.RetryLimitHashedCredentialsMatcher;
import com.bjsxt.relam.MyRealm;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.io.ResourceUtils;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.io.InputStream;


@Configuration
public class ShiroConfig {
    //声明自定义MyRealm的属性
    @Autowired
    private MyRealm myRealm;
    //声明自定义的匹配器
    @Autowired
    private RetryLimitHashedCredentialsMatcher retryLimitHashedCredentialsMatcher;
    /**
     *  编写SecurityManager的bean配置方法
     *  注意:
     *      SpringBoot项目启动的时候会自动的加载配置类的资源，并
     *      将bean方法配置的资源完成初始化设置然后放到Spring容器中
     *      相当于我们之前的bean标签的配置
     *
     */
    @Bean
    protected DefaultWebSecurityManager defaultWebSecurityManager(){
        DefaultWebSecurityManager  defaultWebSecurityManager=new DefaultWebSecurityManager();
        //设置登录认证开启MD5加密
        retryLimitHashedCredentialsMatcher.setHashAlgorithmName("md5");
        retryLimitHashedCredentialsMatcher.setHashIterations(2);
        myRealm.setCredentialsMatcher(retryLimitHashedCredentialsMatcher);
        //将自定义的realm集成到DefaultWebSecurityManager对象中
        defaultWebSecurityManager.setRealm(myRealm);
        //设置Shiro的remember me功能
        defaultWebSecurityManager.setRememberMeManager(rememberMeManager());
        //设置Ehcahe的缓存
        defaultWebSecurityManager.setCacheManager(getEacheManager());
        return defaultWebSecurityManager;
    }
    /**
     * 设置RememberMeManager对象
     */
    public CookieRememberMeManager  rememberMeManager(){
        //创建CookieRememberMeManager对象
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        //1.设置Cookie的参数(Cookie的有效期等)
        cookieRememberMeManager.setCookie(rememberMeCookie());
        //2.对Cookie信息进行加密设置
        cookieRememberMeManager.setCipherKey("1234567890987654".getBytes());
        //返回
        return cookieRememberMeManager;
    }

    /**
     * 设置Cookie信息
     */
    public SimpleCookie rememberMeCookie(){
        SimpleCookie cookie=new SimpleCookie("rememberMe");
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(30 * 24 * 60 * 60);
        return cookie;

    }
    /**
     * 配置Shiro整合Ehcahe的CacheManager
     */
    @Bean
    public EhCacheManager  getEacheManager(){
        //1.创建Shiro的cacheManager对象
        EhCacheManager cacheManager=new EhCacheManager();
        //2.创建EhCahe官方的CacheManager对象
        //获取Ehcahde的配置文件的流对象
        InputStream is=null;
        try {
            is = ResourceUtils.getInputStreamForPath("classpath:ehcache/ehcache-shiro.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        net.sf.ehcache.CacheManager cm=new net.sf.ehcache.CacheManager(is);
        //3.将Ehcache的CacheManager对象存储到Shiro的CacheManager对象中
        cacheManager.setCacheManager(cm);
        //4.返回
        return cacheManager;


    }


    /**
     * 配置Shiro的内置过滤器
     */
    @Bean
    public  ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
        //放行登录页面请求路径
        definition.addPathDefinition("/login", "anon");
        definition.addPathDefinition("/userLogin", "anon");
        definition.addPathDefinition("/logout", "logout");
        definition.addPathDefinition("/**", "user");

        return definition;
    }

    /**
     * 配置页面的shiro标识的解析bean
     */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

}

